Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --overlay and --ro-overlay command line options #167

Closed
wants to merge 2 commits into from

Conversation

wmanley
Copy link

@wmanley wmanley commented Jan 26, 2017

These enable bubblewrap to create overlay mounts. This will be useful for
an ostree-based build system we use where overlayfs ensures that none
of the ostree hard-linked files I checkout get modified. Currently we
use a maze of bash/unshare/mount/sudo/chroot where bubblewrap will be much
nicer.

This commit contains a bit of string manipulation, which isn't
particularly fun to write in C. Hopefully I got it right.

No tests are yet written to exercise this new feature.

Thinking about it I should probably validate that the paths contain no commas to prevent a user from passing arbitrary options to the overlayfs kernel module.

These enable bubblewrap to create overlay mounts.  This will be useful for
an ostree-based build system we use where overlayfs ensures that none
of the ostree hard-linked files I checkout get modified.  Currently we
use a maze of bash/unshare/mount/sudo/chroot where bubblewrap will be much
nicer.

This commit contains a bit of string manipulation, which isn't
particularly fun to write in C.  Hopefully I got it right.

No tests are written to exercise this new feature.
@rh-atomic-bot
Copy link

Can one of the admins verify this patch?
I understand the following commands:

  • bot, add author to whitelist
  • bot, test pull request
  • bot, test pull request once

@cgwalters
Copy link
Collaborator

bot, add author to whitelist

@cgwalters
Copy link
Collaborator

I'm assuming you looked at the rofiles-fuse approach but chose not to?

So...one thing to keep in mind is that currently, this patch will only work if bwrap is setuid - as far as I know, the unprivileged overlayfs (and other fs) discussion is still outstanding.

@alexlarsson
Copy link
Collaborator

Also, this exposes the multi-layer version of overlayfs, which is only supported since Linux 4.0, which is pretty recent, so it may not be a great thing to depend on if you want to e.g. run on current LTS kernels.

@wmanley
Copy link
Author

wmanley commented Jan 26, 2017

I'm assuming you looked at the rofiles-fuse approach but chose not to?

Yes. I need unshare, chroot, mount, etc. anyway so some sort of setuid is needed. I figure I may as well use overlayfs as it's a more general solution than rofiles-fuse. I do a bunch of apt-get installs during my build and you can't guarantee that all of the maintainer-scripts, etc. will not attempt to modify files in-place - and so fail.

I can imagine future optimisations too where I only check-in the upper layer to ostree and have ostree combine layers, rather than having to walk the entire filesystem tree which can be a little slow even with --link-checkout-speedup.

So...one thing to keep in mind is that currently, this patch will only work if bwrap is setuid - as far as I know, the unprivileged overlayfs (and other fs) discussion is still outstanding.

I'll document this caveat.

@wmanley
Copy link
Author

wmanley commented Jan 26, 2017

Also, this exposes the multi-layer version of overlayfs

Yes, but only if you use --ro-overlay or --overlay with more than 2 paths.

which is only supported since Linux 4.0,

I'll document this requirement.

@cgwalters
Copy link
Collaborator

As far as overlayfs vs rofiles-fuse, see this Fedora tracker bug for rpm-ostree, which currently uses rofiles-fuse on top of ostree to implement package layering. I've submitted a few patches.

What we haven't done yet is fully unify the core for rpm-ostree so that the treecompose side also runs unprivileged with rofiles, but I don't think there'll be too many things to patch that I care about.

strappend(&sb, ":");
strappend(&sb, "/oldroot");
/* Resolve absolute symlinks before we remount under /oldroot: */
strappend(&sb, realpath (token, buf));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to handle errors from realpath here.

@alexlarsson
Copy link
Collaborator

I dunno about this. As long as the kernel people are not comfortable exposing overlayfs to users, I'm not confortable taking on the responsibility for that...

@rhatdan
Copy link
Member

rhatdan commented Jan 28, 2017

We have made some changes to overlay to check on the mounters credentials, for access. But opening up overlay without kernel guys saying it ok, would be VERY risky.

@wmanley
Copy link
Author

wmanley commented Jan 31, 2017

I understand the reluctance but I'd like to point out that bubblewrap provides a more restricted environment than by default on linux. Specifically due to PR_SET_NO_NEW_PRIVS. I've looked through some old CVEs related to overlayfs:

  • CVE-2016-1576
    • The overlayfs implementation in the Linux kernel through 4.5.2 does not properly restrict the mount namespace, which allows local users to gain privileges by mounting an overlayfs filesystem on top of a FUSE filesystem, and then executing a crafted setuid program.
    • Requires setuid - would be defeated by PR_SET_NO_NEW_PRIVS
  • CVE-2015-1328
    • The overlayfs implementation in the linux (aka Linux kernel) package before 3.19.0-21.21 in Ubuntu through 15.04 does not properly check permissions for file creation in the upper filesystem directory, which allows local users to obtain root access by leveraging a configuration in which overlayfs is permitted in an arbitrary mount namespace.
    • Ubuntu specific
    • Not defeated by PR_SET_NO_NEW_PRIVS
  • CVE-2015-8660
    • "The ovl_setattr function in fs/overlayfs/inode.c in the Linux kernel through 4.3.3 attempts to merge distinct setattr operations, which allows local users to bypass intended access restrictions and modify the attributes of arbitrary overlay files via a crafted application."
    • Not defeated by PR_SET_NO_NEW_PRIVS

So PR_SET_NO_NEW_PRIVS would have helped some times, but is not enough to make this safe. Perhaps with some additional restrictions this could be made safe, but I can't think of any off the top of my head. Restricting the directories that could be overlaid to ones owned by the user would be one option, but those directories could still contain files owned by root.

I guess I'll just have to carry this patch myself

@alexlarsson
Copy link
Collaborator

@wmanley PR_SET_NO_NEW_PRIVS is required by the kernel to use unprivileged user namespaces too, and still the kernel does not allow such use to mount overlayfs instances. This is the reason we're worrying.

@wmanley wmanley closed this Feb 1, 2017
@georgeto
Copy link

georgeto commented Mar 19, 2021

Works fine for me, also when executed as a non-root user with a non-setuid bubblewrap binary.

@haampie
Copy link

haampie commented Jun 23, 2022

Time to revisit now Linux 5.11 supports it? (And Ubuntu has supported it for a long time through a kernel patch...)

@rhendric
Copy link

Currently a happy user of this patch, also with a non-root user and non-setuid binary.

One note: the overlayfs docs specify that multiple lower layers are given in top-to-bottom order, which means that using this patch, --overlay one:two:three /mnt /mnt.work will result in a stack where three is above one is above two. I'd recommend changing the --overlay syntax to match the top-to-bottom ordering of the Linux kernel, so that --overlay one:two:three /mnt /mnt.work is equivalent to upperdir=one,lowerdir=two:three instead of lowerdir=one:two,upperdir=three.

Maintainers, has the context around overlayfs changed enough in the last five years for you to be more comfortable with this feature? If so, I'd be happy to open a new PR with the above change and make any needed further improvements.

@smcv
Copy link
Collaborator

smcv commented Jan 5, 2023

Maintainers, has the context around overlayfs changed enough in the last five years for you to be more comfortable with this feature? If so, I'd be happy to open a new PR with the above change and make any needed further improvements.

I'd consider a PR that enabled this on kernels where overlayfs is allowed for non-root users, and only when bubblewrap is not setuid (same restriction as --size, --userns-fd, --cap-add).

On kernels where overlayfs is not allowed for non-root users, bubblewrap should not allow it either.

Similarly, when bubblewrap is setuid root, we should not allow this: with a setuid bubblewrap (as used on Debian <= 10, etc.), there's too high a risk of bubblewrap allowing something that the kernel considers unsafe.

die ("Out of memory");
}

strcpy(dest->str + dest->offset, src);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not comfortable with strcpy being used in a codebase that is sometimes setuid root. However careful you've been to allocate enough memory, and to avoid entering this code while privileged, it's just too easy to get wrong. As a minimum, this should use strncpy - but if it can be made to use things like asprintf then that would likely be safer.


strappend(&sb, "lowerdir=");

token = strtok(layers_mut, ":");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really happy about the amount of strtok() here: C string manipulation is notoriously easy to get wrong in security-sensitive ways, and bubblewrap is sometimes setuid root.

I'd prefer it if the layers can be defined in a way that doesn't need to be parsed, perhaps something like

--overlay-upper /foo/upper --overlay-lower /lower1 --overlay-lower /lower2 [--overlay-rw /foo/work] --overlay-onto /foo/merged

with these options only allowed in exactly that order (similar to how the --perms and --size modifiers work).

Comment on lines +208 to +209
in all the <arg choice="plain">LAYERS</arg>. The paths listed in
LAYERS may not contain a comma (,) or a colon (:).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are syntactic restrictions like this, the code should enforce them.

argv += 2;
argc -= 2;
}
else if (strcmp (arg, "--overlay") == 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option should be rejected when privileged, to avoid handing out abilities that the kernel thinks should only be given to root.

argv += 3;
argc -= 3;
}
else if (strcmp (arg, "--ro-overlay") == 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise for this

@smcv
Copy link
Collaborator

smcv commented Jan 6, 2023

I'd consider a PR that enabled this on kernels where overlayfs is allowed for non-root users, and only when bubblewrap is not setuid (same restriction as --size, --userns-fd, --cap-add).

#547 is a continuation of this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants